/**
 * @author Jackson
 * @create 2025/1/15 9:19
 * @description websocket全双工长连接通信+Disruptor无锁队列
 */
package com.zhihao.zhihaopicturebackend.manager.websocket;

/*
    协同编辑的 WebSocket：
        前端根据session中的消息进行相对应的图像变化
        后端主要是通过在同一图片的协同空间进行“消息的广播/分发(相当于通知不同用户的前端，告知其应该去做对应的变换，保持全局一致性)”

    websocket长连接相当于upgrade Http之后的协议，用于此项目中 团队空间协同编编辑图片 的方案设计
        1. 此项目采用最暴力(当然也许不是真正意义上的协同)的方式，即：同一时间仅允许一个用户编辑图片(相当于一个图片编辑空间，一次仅能有一人---类似共享资源)
            这样业务层面去除了需要考虑 不同用户同时编辑可能造成的预期结果不正确等问题

        2. Spring websocketServlet类似于tomcat的HttpServlet，都有最大的请求线程连接数，默认好像是200
            其次，ws和http的请求线程和处理线程都是同一个，即request获取的线程既扮演请求线程连接、且负责后续具体业务逻辑的执行
            如果websocket服务端的处理逻辑需要消耗的时间较长，则体验更差，即200+的线程需要等待较长时间才能等到ws线程的释放
            如果短时间内有大于200的websocket请求进来，则后续200+的其他请求将会阻塞等待(即：并发量低)
          基于此种并发量低的情况，通常解决办法就是：
             “异步调用“---将线程的请求任务 + 线程的执行任务 隔离，将具体耗时的业务执行代码交给新独立线程执行（线程池+任务队列FIFO）
                由于”图片编辑“需要保证”指令执行先后顺序“，
                即：用户A先执行了 ZOOM_IN->ZOOM_OUT->LEFT ROLL...   用户B先执行了 RIGHT ROLL...
                则首先应该执行A的指令，使得用户A看到的结果是符合其预期结果的，所以引入一种高并发下性能较高的Disruptor无锁队列(环形+cas+序号...)
             新的业务仅需向Disruptor队列中合适位置插入“事件”即可，然后通过编写相对应的事件处理方法，实现consumer消费消息/事件

        3. websocket的理解：
            session.add()---向保持长连接的客户端发消息    服务端向客户端发消息

        ## 为什么 WebSocket 握手拦截器能从 HTTP 请求中获取参数

### WebSocket 握手过程中的 HTTP 请求
虽然 WebSocket 是一个持久化的、双向通信的协议，但它是在 HTTP 协议的基础上建立的。WebSocket 连接的建立过程实际上是先通过 HTTP 协议发起一个升级请求，将协议从 HTTP 升级为 WebSocket。

**具体来说，WebSocket 握手过程是这样的：**

1. **客户端发起 HTTP GET 请求:** 客户端向服务器发送一个特殊的 HTTP GET 请求，请求的 URL 通常包含 `ws://` 或 `wss://` 前缀，表示要建立 WebSocket 连接。
2. **服务器响应 HTTP 101 Switching Protocols:** 如果服务器同意建立 WebSocket 连接，则会返回一个 HTTP 101 Switching Protocols响应，并在响应头中包含一些 WebSocket 特定的信息。
3. **客户端和服务器建立 WebSocket 连接:** 客户端和服务器在完成 HTTP 握手后，就可以通过 WebSocket 协议进行实时通信了。

### 握手拦截器在 HTTP 握手阶段起作用
正是因为 WebSocket 连接的建立是基于 HTTP 的，所以我们可以在 WebSocket 握手阶段使用 HTTP 请求对象（如 HttpServletRequest）来获取请求参数。

**握手拦截器的工作时机:**

* 握手拦截器会在 WebSocket 连接建立之前被调用。
* 此时，客户端已经发送了 HTTP 请求，服务器端可以通过 HttpServletRequest 对象获取到请求中的信息。

### 为什么是 HttpServletRequest
* **Servlet 环境:** 绝大多数 WebSocket 实现都是在 Servlet 容器中运行的，比如 Spring WebSocket。在 Servlet 环境中，所有的 HTTP 请求都会被封装成 HttpServletRequest 对象。
* **统一接口:** 通过 HttpServletRequest 接口，我们可以以统一的方式获取各种 HTTP 请求信息，包括请求方法、URL、请求头、请求参数等。
* **方便处理:** 由于 WebSocket 握手阶段本质上就是一个 HTTP 请求，所以直接使用 HttpServletRequest 来处理是最直观、最方便的。

**总结:**

* WebSocket 连接的建立是基于 HTTP 协议的。
* 握手拦截器在 WebSocket 连接建立之前被调用，此时可以获取到 HTTP 请求对象。
* HttpServletRequest 是 Servlet 环境中用于表示 HTTP 请求的标准接口。

**因此，在 WebSocket 握手拦截器中，我们可以通过 HttpServletRequest 对象来获取请求参数和其他 HTTP 请求信息。**

### 额外说明
* **其他 WebSocket 实现:** 虽然 Servlet 环境是最常见的 WebSocket 部署环境，但在其他环境下（如 Node.js），也存在类似的机制来获取 WebSocket 握手过程中的 HTTP 请求信息。
* **WebSocket 消息:** 一旦 WebSocket 连接建立成功，客户端和服务器就可以通过 WebSocket 协议进行实时通信。WebSocket 消息与 HTTP 请求不同，它是一种基于 TCP 的协议，具有更低的延迟和更高的效率。


 */